package com.atchangsha.system.service.impl;

import com.atchangsha.system.common.utils.Result;
import com.atchangsha.system.constant.FoodTableConstants;
import com.atchangsha.system.constant.OrderConstants;
import com.atchangsha.system.dao.FoodTableDao;
import com.atchangsha.system.dao.MenusDao;
import com.atchangsha.system.dao.MenusOrderRelationDao;
import com.atchangsha.system.dto.MenusDTO;
import com.atchangsha.system.dto.PlaceAnOrderDTO;
import com.atchangsha.system.entity.FoodTableEntity;
import com.atchangsha.system.entity.MenusEntity;
import com.atchangsha.system.entity.MenusOrderRelationEntity;
import com.atchangsha.system.service.MenusOrderRelationService;
import com.atchangsha.system.vo.MenusOrderRelationVO;
import com.atchangsha.system.vo.OrderTotalVO;
import com.atchangsha.system.vo.ResultVO;
import com.atchangsha.system.vo.TreePlus;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atchangsha.system.common.utils.PageUtils;
import com.atchangsha.system.common.utils.Query;
import com.atchangsha.system.dao.OrderDao;
import com.atchangsha.system.entity.OrderEntity;
import com.atchangsha.system.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

    @Resource
    private MenusOrderRelationDao menusOrderRelationDao;

    @Resource
    private FoodTableDao foodTableDao;

    @Resource
    private MenusDao menusDao;

    @Resource
    private OrderDao orderDao;

    @Resource
    private MenusOrderRelationService menusOrderRelationService;

    private RedisTemplate redisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        LambdaQueryWrapper<OrderEntity> wrapper = new LambdaQueryWrapper<>();
        List<Integer> arrayList = new ArrayList<>();
        arrayList.add(0);
        arrayList.add(1);
        wrapper.in(OrderEntity::getRemoveFlag, arrayList);
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.like(OrderEntity::getEatMethod, key).or().like(OrderEntity::getFoodTableId, key);
        }
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                wrapper
        );
        IPage<OrderTotalVO> totalPage = new Page<>();

        List<OrderEntity> list = page.getRecords();
        //准备好地集合，将要返回的数据保存在该集合里面
        List<OrderTotalVO> orderTotalVOList = new ArrayList<>();
        //遍历订单
        list.stream().forEach(item -> {
            OrderTotalVO orderTotalVO = new OrderTotalVO();
            //获取餐桌编号
            Long foodTableId = item.getFoodTableId();
            //根据foodTableId查询出桌子实体
            FoodTableEntity tableEntity = foodTableDao.selectOne(new QueryWrapper<FoodTableEntity>().eq("id", foodTableId));
            String chairArea = tableEntity.getChairArea();
            //拼接得到区域几号桌
            String areaCharId = chairArea + "区" + foodTableId;
            orderTotalVO.setAreaCharId(areaCharId);
            //得到下单时间
            Date createTime = item.getCreateTime();
            orderTotalVO.setCreateTime(createTime);
            //得到总价钱
            double price = item.getMoney();
            orderTotalVO.setPrice(price);
            //得到订单号
            Long id = item.getId();
            orderTotalVO.setOrderId(id);
            //得到员工id
            Long waiterId = item.getWaiterId();
            orderTotalVO.setWaiterId(waiterId);
            //得到订单消息
            List<MenusOrderRelationEntity> relationEntityList = menusOrderRelationDao.selectList(new QueryWrapper<MenusOrderRelationEntity>().eq("order_id", id));
            List<MenusOrderRelationVO> relationVOList = relationEntityList.stream().map(relationEntity -> {
                MenusEntity menusEntity = menusDao.selectOne(new QueryWrapper<MenusEntity>().eq("id", relationEntity.getMenusId()));
                String image = menusEntity.getImage();
                MenusOrderRelationVO relationVO = relationEntity.toVO();
                relationVO.setImages(image);
                relationVO.setPrice(menusEntity.getPrice() * relationEntity.getNumber());
                long createTimeTime = createTime.getTime();
                long currentTimeMillis = System.currentTimeMillis();
                long result = currentTimeMillis - createTimeTime;
                String status = "";
                if (result < OrderConstants.MAKING) {
                    status = OrderConstants.MAKING_STATUS;
                } else if (result >= OrderConstants.IN_TRANSIT_BEFORE && result < OrderConstants.IN_TRANSIT_AFTER) {
                    status = OrderConstants.IN_TRANSIT;
                } else {
                    status = OrderConstants.ARRIVED;
                }
                relationVO.setStatus(status);

                return relationVO;
            }).collect(Collectors.toList());
            orderTotalVO.setRelationVOList(relationVOList);

            Date time = item.getTime();
            orderTotalVO.setConsumptionStatus(time == null ? 0 : 1);
            orderTotalVOList.add(orderTotalVO);
        });

        BeanUtils.copyProperties(page, totalPage);
        totalPage.setRecords(orderTotalVOList);

        return new PageUtils(totalPage);
    }

    @Override
    @Transactional
    public Result placeAnOrder(PlaceAnOrderDTO placeAnOrderDTO) {
        Long tableId = placeAnOrderDTO.getTableId();
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setFoodTableId(tableId);
        orderEntity.setMoney(placeAnOrderDTO.getMoney());
        orderEntity.setWaiterId(placeAnOrderDTO.getWorkerId());
        orderEntity.setEatMethod(placeAnOrderDTO.getEatMethod());
        int insert = baseMapper.insert(orderEntity);
        if (insert == 1) {
            //生成订单成功
            OrderEntity entity = baseMapper.selectOne(new QueryWrapper<OrderEntity>().eq("food_table_id", tableId).eq("remove_flag", "0"));
            //得到订单编号
            Long orderId = entity.getId();
            //得到所有的菜品
            List<MenusDTO> list = placeAnOrderDTO.getMenusDTOList();

            List<MenusOrderRelationEntity> collect = list.stream().map(item -> {
                Long menuId = item.getId();
                MenusOrderRelationEntity relationEntity = new MenusOrderRelationEntity();
                relationEntity.setMenusId(menuId);
                relationEntity.setOrderId(orderId);
                relationEntity.setName(item.getName());
                relationEntity.setNumber(item.getNumber());
                relationEntity.setFlavor(item.getFlavor().toString());
                return relationEntity;
            }).collect(Collectors.toList());
            boolean flag = menusOrderRelationService.saveBatch(collect);

            if (!flag) {
                return Result.fail(OrderConstants.OrderEnum.PLACE_AN_ORDER_FAIL);
            } else {
                //将桌子的状态置为已在使用
                FoodTableEntity tableEntity = foodTableDao.selectOne(new QueryWrapper<FoodTableEntity>().eq("id", tableId));
                tableEntity.setStatus(FoodTableConstants.USE);
                int length = foodTableDao.updateById(tableEntity);
                if (length != 1) {
                    return Result.fail(OrderConstants.OrderEnum.PLACE_AN_ORDER_FAIL);
                }
                return Result.ok(OrderConstants.OrderEnum.PLACE_AN_ORDER_SUCCESS);
            }
        }
        return Result.fail(OrderConstants.OrderEnum.PLACE_AN_ORDER_FAIL);
    }

    //TODO 菜单删除后，订单里面菜单编号是不存在的
    @Override
    @Transactional
    public Result listAll() {
        List<OrderEntity> list = baseMapper.selectList(new QueryWrapper<OrderEntity>().eq("remove_flag", "0"));
        //准备好地集合，将要返回的数据保存在该集合里面
        List<OrderTotalVO> orderTotalVOList = new ArrayList<>();
        //遍历订单
        list.stream().forEach(item -> {
            OrderTotalVO orderTotalVO = new OrderTotalVO();
            //获取餐桌编号
            Long foodTableId = item.getFoodTableId();
            //根据foodTableId查询出桌子实体
            FoodTableEntity tableEntity = foodTableDao.selectOne(new QueryWrapper<FoodTableEntity>().eq("id", foodTableId));

            String chairArea = tableEntity.getChairArea();
            //拼接得到区域几号桌
            String areaCharId = chairArea + "区" + foodTableId;
            orderTotalVO.setAreaCharId(areaCharId);
            //得到下单时间
            Date createTime = item.getCreateTime();
            orderTotalVO.setCreateTime(createTime);
            //得到总价钱
            double price = item.getMoney();
            orderTotalVO.setPrice(price);
            //得到订单号
            Long id = item.getId();
            orderTotalVO.setOrderId(id);
            //得到员工id
            Long waiterId = item.getWaiterId();
            orderTotalVO.setWaiterId(waiterId);
            //得到订单消息
            List<MenusOrderRelationEntity> relationEntityList = menusOrderRelationDao.selectList(new QueryWrapper<MenusOrderRelationEntity>().eq("order_id", id));
            List<MenusOrderRelationVO> relationVOList = relationEntityList.stream().map(relationEntity -> {
                MenusEntity menusEntity = menusDao.selectOne(new QueryWrapper<MenusEntity>().eq("id", relationEntity.getMenusId()));
                String image = menusEntity.getImage();
                MenusOrderRelationVO relationVO = relationEntity.toVO();
                relationVO.setImages(image);
                relationVO.setPrice(menusEntity.getPrice() * relationEntity.getNumber());
                long createTimeTime = createTime.getTime();
                long currentTimeMillis = System.currentTimeMillis();
                long result = currentTimeMillis - createTimeTime;
                String status = "";
                if (result < OrderConstants.MAKING) {
                    status = OrderConstants.MAKING_STATUS;
                } else if (result >= OrderConstants.IN_TRANSIT_BEFORE && result < OrderConstants.IN_TRANSIT_AFTER) {
                    status = OrderConstants.IN_TRANSIT;
                } else {
                    status = OrderConstants.ARRIVED;
                }
                relationVO.setStatus(status);

                return relationVO;
            }).collect(Collectors.toList());
            orderTotalVO.setRelationVOList(relationVOList);

            orderTotalVOList.add(orderTotalVO);
        });
        return Result.ok().setResult(orderTotalVOList);
    }

    @Override
    public Result updateOrder(OrderEntity toEntity) {
        if (baseMapper.updateById(toEntity) != 1) {
            return Result.fail(OrderConstants.OrderEnum.UPDATE_FAIL);
        }
        return Result.ok(OrderConstants.OrderEnum.UPDATE_SUCCESS).setResult(toEntity.toVO());
    }

    @Override
    public ResultVO sum() {
        //返回对象
        ResultVO resultVO = new ResultVO();
        // 数据库中的最小年份
        String minYear = orderDao.getYear().substring(0, 4);
        // 数据库中的最大年份
        String maxYear = orderDao.getMaxYear().substring(0, 4);
        // List集合记录年份集合
        List<TreePlus> yearResult = new ArrayList<>();
        for (int year = Integer.valueOf(minYear); year <= Integer.valueOf(maxYear); year++) {
            // 年收益
            Double yearSum = Double.valueOf(0);
            // 控制年份的
            TreePlus yearNum = new TreePlus();
            //List集合记录年份中的月份集合
            List<TreePlus> list = new ArrayList<>();
            for (int month = 1; month <= 12; month++) {
                String monthTmp = null;
                if (month <= 9) {
                    monthTmp = "0" + month;
                } else {
                    monthTmp = String.valueOf(month);
                }
                //year年month月的收益
                String time = year + "-" + monthTmp + "%";
                Double monthSum = orderDao.getSum(time);
                TreePlus monthNum = new TreePlus(month, monthSum);
                //将每个月份的集合都存起来
                list.add(monthNum);
                yearSum += monthSum;
            }
            yearNum.setKey(year);
            yearNum.setMoney(yearSum);
            yearNum.setChild(list);
            yearResult.add(yearNum);
        }
        resultVO.setResult(yearResult);
        return resultVO;
    }

    @Override
    public ResultVO sumListAll() {
        List<OrderEntity> orderEntities = orderDao.selectList(new LambdaQueryWrapper<OrderEntity>().eq(OrderEntity::getRemoveFlag, 1).orderByAsc(OrderEntity::getCreateTime));
        //返回对象
        ResultVO resultVO = new ResultVO();
        // 数据库中的最小年份
        String minYear = orderDao.getYear().substring(0, 4);
        // 数据库中的最大年份
        final String[] maxYear = {orderDao.getMaxYear().substring(0, 4)};
        // List集合记录年份集合
        List<TreePlus> yearResult = new ArrayList<>();
        //前一个元素的年份
        Integer purYear = 1970;
        // 前一个元素的月份
        final Integer[] month = {1};
        // 控制年份的
        final TreePlus[] yearNum = {new TreePlus()};
        // 控制月份的
        final TreePlus[] monthNum = {new TreePlus()};
        //月收益
        final Double[] monthSum = {Double.valueOf(0)};
        //年收益
        final Double[] yearSum = {Double.valueOf(0)};
        //List集合记录年份中的月份集合
        final List<TreePlus>[] list = new List[]{new ArrayList<>()};
        orderEntities.stream().forEach(item -> {

            //当前年份
            Integer curYear = Integer.parseInt(item.getCreateTime().toString().substring(0, 4));

            //当前月份
            Integer curMonth = Integer.parseInt(item.getCreateTime().toString().substring(5, 7));

            // 当前年份和前一个元素的年份相等
            if (purYear == curYear) {
                //当前月份前一个元素月份相等
                if (curMonth == month[0]) {
                    monthSum[0] += item.getMoney();
                    month[0] = curMonth;
                }
                //当前月份前一个元素月份不相等
                else {
                    monthNum[0].setMoney(monthSum[0]);
                    monthNum[0].setKey(month[0]);
                    list[0].add(monthNum[0]);
                    monthNum[0] = new TreePlus();
                    yearSum[0] += monthSum[0];
                }
            }
            //当前年份和前一个元素的年份部相等
            else {
                yearNum[0].setChild(list[0]);
                yearNum[0].setKey(purYear);
                yearNum[0].setMoney(yearSum[0]);
                list[0] = new ArrayList<TreePlus>();
                yearSum[0] = Double.valueOf(0);
                yearResult.add(yearNum[0]);
                yearNum[0] = new TreePlus();
            }
            resultVO.setResult(yearResult);
        });

        System.out.println(resultVO);

        return resultVO;
    }
}